#include <sys/msg.h>
#include <stdio.h>
#include <string.h>
void send_message(int);
void receive_message(int);
/* 消息结构体，注意第一个元素必须是type */
typedef struct{
	long type; // 必须大于1，否则发送消息失败
	int id;
	char name[8];
}my_message;
int main(int argc,char* argv[])
{
	if(argc < 3)
	{
		printf("incorrect parameter\n");
		return 1;
	}
	// 可以用ftok生成key，注意argv[2]必须是一个实际存在的路径，不然函数返回-1
	// key_t k = ftok(argv[2],0);
	// 直接使用数字 
	key_t k = atoi(argv[2]);
	// 打开/创建消息队列
	int msgqid = 0;
	if((msgqid = msgget(k,IPC_CREAT | 0777)) == -1)
	{
		perror("msgget error");
		return 1;
	}
	if(strcmp("send",argv[1]) == 0)
	{
		send_message(msgqid);
	}
	else if(strcmp("receive",argv[1]) == 0)
	{
		receive_message(msgqid);
	}
	else
	{
		printf("incorrect parameter\n");
		return 1;
	}
	// 删除队列
	if(msgctl(msgqid,IPC_RMID,NULL) == -1)
	{
		perror("remove message queue error");
		return 1;
	}
	return 0;
}
/* 发送消息方法 */
void send_message(int msgqid)
{
	my_message m = {0,0,{'\0'}};
	int type = 1;
	// 消息的大小，注意要减去type的大小
	size_t bytes = sizeof(my_message) - sizeof(long);
	struct msqid_ds ds;
	int c;
	while(1)
	{
		printf("input id name\n");
		scanf("%d %7s",&m.id,m.name);
		m.type = type;
		if(msgsnd(msgqid,(void*)&m,bytes,0) == -1)
		{
			perror("msgsnd error");
			break;
		}
		type++;
		if(-1 == msgctl(msgqid,IPC_STAT,&ds))
		{
			perror("msgctl error");
		}
		else
		{
			printf("msgqnum = %u\n",(unsigned int)ds.msg_qnum);
		}
		// 重置name字符数组
		memset(m.name,'\0',8);
		// 清空标准输入的缓冲区的内容
		while ((c=getchar()) != '\n' && c!=EOF);
	}
}
/* 接受消息方法 */
void receive_message(int msgqid)
{
	my_message m;
	// 消息的大小，注意要减去type的大小
	size_t bytes = sizeof(my_message) - sizeof(long);
	struct msqid_ds ds;
	while(1)
	{
		if(msgrcv(msgqid,(void*)&m,bytes,0,0) == -1)
		{
			perror("msgrcv error");
			break;
		}
		else
		{
			printf("type = %d;id = %d;name = %s\n",(int)m.type,m.id,m.name);
		}
		if(-1 == msgctl(msgqid,IPC_STAT,&ds))
		{
			perror("msgctl error");
		}
		else
		{
			printf("msgqnum = %u\n",(unsigned int)ds.msg_qnum);
		}
	}
}
